﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using AY64.Model;

namespace AY64
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //第一步：获取当前目录
            //第二步：获取当前目录所有uc后缀的文件
            //第三步：通过文件名获取MusicID
            //第四步：提交MusicID到网易云音乐API服务获取歌曲详细信息并提取歌曲名称，没有信息的则以MusicID为歌曲名称
            //第五步：解码uc文件为mp3文件，并以上一步获取的名称进行命名
            _musicLst.Clear();
            txtMsg.Clear();

            Thread runThread = new Thread(delegate () { runCatchMusicTheard(); }) { Name = "runCatchMusic",IsBackground = true };
            runThread.Start();
        }

        private void runCatchMusicTheard()
        {
            ShowMessage("采集歌曲信息开始！");
            GetMusicList(txtSrc.Text);
            if (_musicLst.Count > 0)
            {
                ShowMessage("联网采集歌曲名称信息开始！");
                foreach (var item in _musicLst)
                {
                    GetNameFromApiJson(item.ID);
                    _musicCount--;
                }
            }
            ShowMessage("采集歌曲信息结束！");
        }

        //ShowMessage(string.Format("",));

        List<MusicInfo> _musicLst = new List<MusicInfo>();
        int _musicCount = 0;
        //Dictionary<string,string> musicLst = new Dictionary<string, string>();

        private void GetMusicList(string srcDirectory)
        {
            try
            {
                if (Directory.Exists(srcDirectory))
                {
                    //获取当前目录下所有后缀为uc的文件
                    string[] mlst = Directory.GetFiles(srcDirectory, "*.uc");
                    if (mlst.Length > 0)
                    {
                        _musicCount = mlst.Length;
                        ShowMessage(string.Format("当前目录共有{0}个歌曲需要进行转码", mlst.Length));
                        //获取文件原始名称
                        foreach (var item in mlst)
                        {
                            string fName = Path.GetFileNameWithoutExtension(item);
                            string[] splitName = fName.Split('-');
                            if (splitName.Length == 3)
                            {
                                //添加编号、源文件路径
                                _musicLst.Add(new MusicInfo() { ID = int.Parse(splitName[0]), FileSrcPath = item,FileDestPath = Path.Combine(txtOut.Text, fName+".mp3")});
                                ShowMessage(string.Format("[{0}]文件名解析完成{1}", _musicCount, fName));
                            }
                            else
                            {
                                ShowMessage(string.Format("[{0}]文件名解析失败{1}", _musicCount, fName));
                            }
                            _musicCount--;
                        }
                    }
                    _musicCount = mlst.Length;
                }
                else
                {
                    ShowMessage(string.Format("目录{0}不存在，请检查目录配置！",srcDirectory));
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 获取歌曲名称数据
        /// </summary>
        /// <param name="mid"></param>
        private void GetNameFromApiJson(int mid)
        {
            try
            {
                ShowMessage(string.Format("[{0}]开始获取编号为{1}的歌曲名称", _musicCount,mid));
                string url = string.Format("https://api.imjad.cn/cloudmusic/?type=detail&id={0}", mid);
                string rtnStr = HttpHelper.GetResponseUTF(url, "get", "");
                if (!string.IsNullOrEmpty(rtnStr))
                {
                    //JsonConvert.DeserializeObject<>
                    MusicDetail runInfo = JsonConvert.DeserializeObject<MusicDetail>(rtnStr);
                    if (runInfo!= null)
                    {
                        MusicInfo minfo = _musicLst.Find(t => t.ID == mid);
                        if (minfo != null)
                        {
                            minfo.Name = runInfo.songs[0].name;
                            minfo.Artist = runInfo.songs[0].ar != null ? runInfo.songs[0].ar[0].name : "";
                            //minfo.FileDestPath = Path.Combine(txtOut.Text, minfo.ID + minfo.Name + ".mp3");
                            minfo.FileDestPath = Path.Combine(txtOut.Text, string.Format("{0}-{1}-{2}.mp3", minfo.ID, minfo.Artist, minfo.Name));
                            minfo.LyricDestPath = Path.Combine(txtOut.Text, string.Format("{0}-{1}-{2}.lrc", minfo.ID, minfo.Artist, minfo.Name));
                        }
                        ShowMessage(string.Format("当前编号为{0}的歌曲名称为‘{1}’", mid, runInfo.songs[0].name));
                        OutMP3(minfo.FileSrcPath, minfo.FileDestPath);
                        GetLyricFromApiJson(mid);
                    }
                }
                else
                {
                    ShowMessage(string.Format("当前编号为{0}的歌曲未能获取到歌曲信息！", mid));
                }
                
                //return "";

            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
                Console.WriteLine(ex.Message);
                //return "";
            }
        }

        /// <summary>
        /// 获取歌词数据
        /// </summary>
        /// <param name="mid"></param>
        private void GetLyricFromApiJson(int mid)
        {
            try
            {
                ShowMessage(string.Format("开始获取编号为{0}的音乐歌词", mid));
                string url = string.Format("https://api.imjad.cn/cloudmusic/?type=lyric&id={0}", mid);
                string rtnStr = HttpHelper.GetResponseUTF(url, "get", "");
                if (!string.IsNullOrEmpty(rtnStr))
                {
                    //JsonConvert.DeserializeObject<>
                    MusicLyric runInfo = JsonConvert.DeserializeObject<MusicLyric>(rtnStr);
                    if (runInfo != null)
                    {
                        MusicInfo minfo = _musicLst.Find(t => t.ID == mid);
                        if (minfo != null && runInfo.lrc != null)
                        {
                            minfo.Lyric =  runInfo.lrc.lyric;
                            OutLyc(minfo.ID, minfo.Lyric, minfo.LyricDestPath);
                        }
                        else
                        {
                            ShowMessage(string.Format("当前编号为{0}的歌曲{1}未采集到歌词", mid, minfo.Name));
                        }
                    }
                }
                else
                {
                    ShowMessage(string.Format("当前编号为{0}的歌曲未能获取到歌曲信息！", mid));
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
                Console.WriteLine(ex.Message);
            }
        }

        private void OutMP3(string srcFile,string destFile)
        {
            try
            {
                if (!Directory.Exists(txtOut.Text))
                {
                    Directory.CreateDirectory(txtOut.Text);
                }
                ShowMessage(string.Format("文件{0}转码开始...", srcFile));
                using (FileStream outputStream = new FileStream(destFile, FileMode.Create))
                {
                    using (FileStream fs = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        byte[] filebytes = new byte[fs.Length];
                        int readCount = fs.Read(filebytes, 0, Convert.ToInt32(fs.Length));
                        for (int i = 0; i < fs.Length; i++)
                        {
                            filebytes[i] ^= 0xa3;
                        }

                        outputStream.Write(filebytes, 0, readCount);
                    }
                    
                }
                ShowMessage(string.Format("文件{0}转码输出到{1}完成！", srcFile, destFile));
                
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
                Console.WriteLine(ex.Message);
            }
        }

        private void OutLyc(int mid, string lycCont,string destFile)
        {
            try
            {
                if (!Directory.Exists(txtOut.Text))
                {
                    Directory.CreateDirectory(txtOut.Text);
                }
                ShowMessage(string.Format("歌曲{0}输出歌词开始...", mid));
                using (FileStream outputStream = new FileStream(destFile, FileMode.Create))
                {
                    byte[] filebytes = System.Text.Encoding.Default.GetBytes(lycCont);
                    outputStream.Write(filebytes, 0, filebytes.Length);
                }
                ShowMessage(string.Format("歌词文件{0}获取完成！", destFile));
            }
            catch (Exception ex)
            {
                ShowMessage(ex.Message);
                Console.WriteLine(ex.Message);
            }
        }

        

        private int _msgLins = 0;
        private void ShowMessage(string msg)
        {
            if (txtMsg.InvokeRequired)
            {
                Action<string> ac = new Action<string>(ShowMessage);
                txtMsg.Invoke(ac, msg);
            }
            else
            {
                //当行数达到300，则清空文本框
                if (_msgLins == 300)
                {
                    txtMsg.Clear();
                    _msgLins = 0;
                }
                txtMsg.Text = txtMsg.Text + (DateTime.Now.ToString() + " " + "音乐引擎：" + msg + "\r\n");
                txtMsg.SelectionStart = txtMsg.Text.Length;
                txtMsg.ScrollToCaret();

                _msgLins++;
            }
        }
    }
}
